package com.snow.rbac.util;

import com.alibaba.fastjson.JSON;
import com.snow.rbac.entity.UserInfo;
import io.jsonwebtoken.*;
import org.springframework.beans.BeanUtils;

import javax.crypto.spec.SecretKeySpec;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * All rights Reserved, Designed By www.cusc.com
 *
 * @author yanke
 * @Title: JwtUtils
 * @Package com.snow.rbac.util
 * @Description:类描述
 * @Email yanke@cu-sc.com
 * @version: v1.0.0
 * @date: 2021/7/2/0002 11:00
 * @Copyright: 2021  www.faw.com.cn Inc. All rights reserved. <br/>
 * Modification History:<br/>
 * Date         Author          Version            Description<br/>
 * *---------------------------------------------------------*<br/>
 * 2021/7/2/0002     Administrator           v1.0.0               修改原因<br/>
 * @since JDK 1.8
 */
public class JwtUtils {

    private static Long exp = 1000L * 60 * 24;
    private static String signKey = "key";
    private static SecretKeySpec secretKeySpec = new SecretKeySpec(signKey.getBytes(), SignatureAlgorithm.HS256.getJcaName());

    public static void main(String[] args) throws Exception {
        UserInfo bean = new UserInfo();
        bean.setId(1141248909821509633L);
        bean.setUsername("zhangsan");
        bean.setPassword("123456");
        Map map = JSON.parseObject(JSON.toJSONString(bean), Map.class);
        String jwt = createJwt(map);
        System.out.println(jwt);
        UserInfo userInfo = parserJwt(jwt, UserInfo.class);
        System.out.println(userInfo);
    }

    /**
     * 生成token
     *
     * @return
     */
    public static String createJwt(Map map) {
        SecretKeySpec secretKeySpec = new SecretKeySpec(signKey.getBytes(), SignatureAlgorithm.HS256.getJcaName());
        //生成token
        Long now = System.currentTimeMillis() + exp;//30秒过期
        JwtBuilder jwtBuilder = Jwts.builder();
        Optional.ofNullable(map.get("id")).ifPresent(v -> jwtBuilder.setId(map.get("id").toString()));
        Optional.ofNullable(map.get("username")).ifPresent(v -> jwtBuilder.setSubject(map.get("username").toString()));
        jwtBuilder.setIssuedAt(new Date());//签发时间
        jwtBuilder.setExpiration(new Date(now));//过期时间
        jwtBuilder.signWith(SignatureAlgorithm.HS256, secretKeySpec);
        Map objMap = new HashMap();
        objMap.put("obj", map);
        jwtBuilder.setClaims(objMap);
        String token = jwtBuilder.compact();
        return token;
    }

    public static String createJwt(Object t) {
        SecretKeySpec secretKeySpec = new SecretKeySpec(signKey.getBytes(), SignatureAlgorithm.HS256.getJcaName());
        //生成token
        Long now = System.currentTimeMillis() + exp;//30秒过期
        JwtBuilder jwtBuilder = Jwts.builder();
        UserInfo userInfo = new UserInfo();
        if (t instanceof UserInfo) {
            userInfo = (UserInfo) t;
            Long id = userInfo.getId();
            String username = userInfo.getUsername();
            Optional.ofNullable(id).ifPresent(v -> jwtBuilder.setId(id.toString()));
            Optional.ofNullable(username).ifPresent(v -> jwtBuilder.setSubject(username));
        }
        jwtBuilder.setIssuedAt(new Date());//签发时间
        jwtBuilder.setExpiration(new Date(now));//过期时间
        jwtBuilder.signWith(SignatureAlgorithm.HS256, secretKeySpec);
        Map objMap = new HashMap();
        objMap.put("obj", JSON.parseObject(JSON.toJSONString(userInfo), Map.class));
        jwtBuilder.setClaims(objMap);
        String token = jwtBuilder.compact();
        return token;
    }

    public static <T> T parserJwt(String token, Class<T> clazz) throws Exception {
//        T t = clazz.getDeclaredConstructor().newInstance();
        T t = BeanUtils.instantiateClass(clazz);
        JwtParser parser = Jwts.parser().setSigningKey(secretKeySpec);
        Claims claims = parser.parseClaimsJws(token).getBody();
        Map map = claims.get("obj", Map.class);
        t = JSON.parseObject(JSON.toJSONString(map), clazz);
        return t;
    }

    public static UserInfo parserJwt(String token) {
        JwtParser parser = Jwts.parser().setSigningKey(secretKeySpec);
        Claims claims = parser.parseClaimsJws(token).getBody();
        Map map = claims.get("obj", Map.class);
        UserInfo userInfo = JSON.parseObject(JSON.toJSONString(map), UserInfo.class);
        return userInfo;
    }
}
